import Bead from "./Bead";
import { GLTFLoader } from "three/addons/Addons.js";
import { BeadData } from "./BraceleData";

export default class BeadPool {
    loader = new GLTFLoader();
    // 对象池 { path: [Bead, Bead, ...], path2: [Bead2, Bead2, ...], ... }
    _pools = new Map();
    // 加载过的gltf.scene， { path: gltf.scene, path2: gltf2.scene, ... }
    loadedScenes = new Map();
    constructor() { }

    /**
     * 从池中获取一个珠子，如果有闲置的直接返回，否则生成一个新的
     * @param {BeadData} beadData
     * @returns 
     */
    pop(beadData) {
        const path = beadData.path;

        // 从缓存获取可用实例
        if (this._pools.has(path)) {
            const pool = this._pools.get(path);
            if (pool.length > 0) {
                const bead = pool.pop();
                bead.mesh.visible = true;
                bead.setData(beadData);
                return bead;
            }
        }

        if (this.loadedScenes.has(path)) {
            const bead = new Bead(beadData);
            const scene = this.loadedScenes.get(path);
            bead.add(scene.clone());
            return bead;
        }

        const bead = new Bead(beadData);
        this.loader.load(path, (gltf) => {
            const scene = gltf.scene;
            this.loadedScenes.set(path, scene);
            bead.add(scene);
        });

        return bead;
    }

    /**
     * 回收珠子实例
     * @param {Bead} bead 
     */
    push(bead) {
        const path = bead.path;
        if (!this._pools.has(path)) {
            this._pools.set(path, []);
        }

        bead.mesh.visible = false;
        this._pools.get(path).push(bead);
    }
}